在 Day 8,我們模擬了「完全沒有 Session」的極端情境,但這個情境又回到過去的老路:
到了現在,工程師需要一種更聰明的解法,而且包含以下優點:
於是, JWT(JSON Web Token) 登場了。
JWT 是一種開放標準(RFC 7519),它的設計理念是:
把使用者資訊編碼成一個 Token,並透過簽名驗證真偽。
這樣一來:
不免俗的,叫紹到JWT就需要介紹他的結構,一個典型的 JWT 長這樣:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkVyaWMiLCJyb2xlIjoiVVNFUiIsImlhdCI6MTUxNjIzOTAyMn0.
TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
它由三個部分組成,用「.
」分隔:
Header(頭部)
說明演算法與 Token 類型。
例如:
{
"alg": "HS256",
"typ": "JWT"
}
Payload(負載)
存放使用者相關的資訊。
例如:
{
"sub": "1234567890",
"name": "Eric",
"role": "USER",
"iat": 1516239022,
"exp": 1516242622
}
常見欄位:
sub
→ 使用者 IDrole
→ 使用者角色iat
→ 發行時間 (Issued At)exp
→ 過期時間 (Expire Time)Signature(簽名)
由 Header + Payload + Secret 產生,用來驗證 Token 是否被竄改。
計算方式:
HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret
)
只要 Payload 被竄改,簽名就會對不上,伺服器立刻能檢查出來。
駭客一來幾乎沒有辦法拿到解碼的Secret,因此不能去修改內容來擴增自己的權限。
有了JWT,密碼就變得更加安全有保障。
在前幾天,我們有說到Token有一個問題,那就是沒有辦法主動失效的問題,JWT雖然解決了Token,但仍然是一種Token,所以仍然沒有辦法主動失效,這點想要特別點出來讓大家理解。
我自己在接觸到JWT的時候就有遇到這個問題
exp
)JWT 本身可以設定一個到期時間,超過時間後,伺服器會自動拒絕它。
有些情境需要 立即收回 Token,例如:
問題在於:
JWT 發出去之後,伺服器無法「主動收回」它,因為 JWT 是 Stateless,不存在伺服器的記憶體。
實務上會搭配以下機制:
回顧一下今天學到的東西,我們可以知道JWT的出現跟他想要解決的問題,讓我們整理成以下的重點:
今天我們完整認識了 JWT 的結構:
我們也釐清了:
這就是 JWT 的強大之處:無狀態、自帶資訊、防竄改,同時也是它的限制所在。
明天(Day 10),我們將實際用 Java 原生程式碼來手動實作一個簡單的 JWT:
大家明天見!